//
// Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//
//
#ifndef Green_PcSpacing_H
#define Green_PcSpacing_H

#include <vector>

#include "Defines.h"

namespace Green {

  class Generator;
  class ConstraintSet;
  class VmMapper;
  class GenPC;

  /*!
    \class PcSpacing
    \brief Consider PC vicinity spacing from all PEs when generating instruction or data targets
  */

  class PcSpacing {
  public:
    static void Initialize();  //!< Initialization interface.
    static void Destroy();     //!< Destruction clean up interface.
    inline static PcSpacing* Instance() { return mspPcSpacing; } //!< Access PcSpacing instance.
    void SignUp(const Generator* pGen); //!< Generator signup with the PC spacing module.
    const ConstraintSet* GetPcSpaceConstraint(); //!< Get PC spaces constraint.
    const ConstraintSet* GetBranchPcSpaceConstraint(const VmMapper* pVmMapper, uint32 instrSize); //!< Get PC spaces constraint for branch instruction.
  private:
    PcSpacing(); //!< Default constructor.
    COPY_CONSTRUCTOR_ABSENT(PcSpacing);
    ~PcSpacing(); //!< Destructor.
    ASSIGNMENT_OPERATOR_ABSENT(PcSpacing);
    void AugmentConstraint(cuint64 pcValue, cuint32 instrSpace, ConstraintSet* constr); //!< Add the range starting at pcValue of length instrSpace to the specified constraint.
  private:
    ConstraintSet* mpPcConstraint; //!< Pointer to a PC spacing constraint object for normal access.
    ConstraintSet* mpBranchPcConstraint; //!< Pointer to a PC spacing constraint object for own branch access.
    std::vector<const Generator* > mGenerators; //!< List of generators with distinct PCs.
    static PcSpacing* mspPcSpacing; //!< Static pointer to PcSpacing object.
  };

}

#endif
